package com.hk.app.utils;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.hk.commons.CacheConstants;
import com.hk.commons.HqlFilter;
import com.hk.commons.HttpUtils;
import com.hk.commons.StringHelper;
import com.hk.commons.entity.sys.SendMsgPass;
import com.hk.commons.utils.sys.MD5Crypter;
import com.hk.service.sys.ISysMsgPass;

@Component
public class SendMsgCilent {

	private Logger logger = LoggerFactory.getLogger(SendMsgCilent.class);

	@Value("${msg.host}")
	private String host;

	@Autowired
	private ISysMsgPass msgService;
	@Value("${msg.startText}")
	private String startText;

	@Value("${msg.endText}")
	private String endText;

	@Value("${msg.userid}")
	private String userid;

	@Value("${msg.account}")
	private String account;

	@Value("${msg.password}")
	private String password;

	@Value("${msg.mm}")
	private String mm;

	private static Map<String, String> params = new HashMap<>();

	@PostConstruct
	public void init() {
		SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
		String timestamp = sf.format(System.currentTimeMillis());
		String originalString = this.account + this.password + timestamp;
		String sign = MD5Crypter.md5Encrypt(originalString);
		params.put("userid", this.userid);
		params.put("account", this.account);
		params.put("password", this.password);
		params.put("timestamp", timestamp);
		params.put("sign", sign);
		params.put("sendTime", "");
		params.put("action", "send");
		params.put("extno", "");
	}

	public Map<String, String> senMsgRoute(String mobile, String content,
			String ifJG, String channel) {
		logger.info("发送短信入参：mobile={},content={},ifJG={},channel={}", mobile,
				content, ifJG, channel);
		Map<String, String> resultMap = new HashMap<>();
		boolean result = false;
		String company = "JIGUANG";
		if (channel != null) {
			String channelString;
			switch (channel) {
			case "1":
				channelString = "IOS";
				break;
			case "2":
				channelString = "Android";
				break;
			case "3":
				channelString = "PC";
				break;
			default:
				channelString = "IOS";
				break;
			}
			logger.info("pre getMsgCode  moblie: {},channel={}", mobile,
					channelString);
		}
		if (StringHelper.isNotEmpty(ifJG)) {// 可以走极光通道，则可选
			HqlFilter filter = new HqlFilter();
			List<SendMsgPass> msgList = msgService.findByFilter(filter);
			switch (msgList.get(0).getChannelType()) {
			case 1:// 只开启极光
				if (sendMsgByJG(mobile, content)) {
					result = true;
					company = "JIGUANG";
				} else {
					logger.info("极光短信异常，切换为亿佳,mobile={}", mobile);
					if (sendMsg(mobile, content)) {
						result = true;
						company = "YIJIA";
					}
				}
				break;
			case 2:// 只开启亿佳
				if (sendMsg(mobile, content)) {
					company = "YIJIA";
					result = true;
				} else {
					logger.info("亿佳短信异常，切换为极光,mobile={}", mobile);
					if (sendMsgByJG(mobile, content)) {
						result = true;
						company = "JIGUANG";
					}
				}
				break;
			case 3:// 都开启
				int random = (int) (Math.random() * 100);
				List<Integer> list = new ArrayList<Integer>();
				for (SendMsgPass msgPass : msgList) {
					int scale = msgPass.getScale();
					list.add(scale);
				}
				Collections.sort(list);
				int minScale = list.get(0);
				int maxScale = list.get(list.size() - 1);
				HqlFilter minFilter = new HqlFilter();
				minFilter.addEQFilter("scale", minScale);
				SendMsgPass minMsgPass = msgService.findByFilter(minFilter)
						.get(0);
				HqlFilter maxFilter = new HqlFilter();
				maxFilter.addEQFilter("scale", maxScale);
				List<SendMsgPass> maxMsgList = msgService
						.findByFilter(maxFilter);
				SendMsgPass maxMsgPass;
				if (maxMsgList.size() > 1) {
					maxMsgPass = maxMsgList.get(1);
				} else {
					maxMsgPass = maxMsgList.get(0);
				}
				int minId = Integer.parseInt("" + minMsgPass.getId());
				int maxId = Integer.parseInt("" + maxMsgPass.getId());
				if (random < minScale) {
					switch (minId) {
					case 1:// 亿佳
						if (sendMsg(mobile, content)) {
							company = "YIJIA";
							result = true;
						} else {
							if (sendMsgByJG(mobile, content)) {
								result = true;
								company = "JIGUANG";
							}
						}
						break;
					case 2:
						if (sendMsgByJG(mobile, content)) {
							result = true;
							company = "JIGUANG";
						} else {
							if (sendMsg(mobile, content)) {
								result = true;
								company = "YIJIA";
							}
						}
						break;
					default:
						break;
					}
				} else {
					switch (maxId) {
					case 1:// 亿佳
						if (sendMsg(mobile, content)) {
							company = "YIJIA";
							result = true;
						} else {
							if (sendMsgByJG(mobile, content)) {
								result = true;
								company = "JIGUANG";
							}
						}
						break;
					case 2:
						if (sendMsgByJG(mobile, content)) {
							result = true;
							company = "JIGUANG";
						} else {
							if (sendMsg(mobile, content)) {
								result = true;
								company = "YIJIA";
							}
						}
						break;
					default:
						break;
					}
				}
				break;
			default:
				logger.info("未开启短信");
				break;
			}
		} else {// 不能使用极光，只走亿佳通道
			if (sendMsg(mobile, content)) {
				company = "YIJIA";
				result = true;
			}
		}
		resultMap.put("result", String.valueOf(result));
		resultMap.put("company", company);
		return resultMap;
	}

	/**
	 * 短信发送，
	 * 
	 * @param mobile
	 *            接收短信为英文,（英文逗号）间隔开
	 * @param content
	 * @param status
	 *            0 验证码
	 * @return
	 */
	public boolean sendMsg(String mobile, String content) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(this.startText);
		buffer.append(":");
		buffer.append(content);
		buffer.append(this.endText);

		try {
			params.put("content", new String(buffer.toString()
					.getBytes("UTF-8")));
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		params.put("mobile", mobile);
		String result = "";
		boolean t = false;
		try {
			result = HttpUtils.invokePostForm(this.host, params, 5000);


			Returnsms sb = new Returnsms();
			sb = this.XMLStringToBean(result);
			logger.info("params:{}", params);
			logger.info("Send msg Result:{}", result);
			if (sb.getMessage().equals("ok")) {
				t = true;
			} else {
				logger.info("Send msg fail mobile:{} , Result:{}", mobile,
						result);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return t;
	}

	public Map<String, String> validate(String code, String mobile, int status) {
		// 发送验证码
		Map<String, String> params = new HashMap<>();
		Map<String, String> resultMap = new HashMap<String, String>();
		params.put("code", code);
		String jgApiKey = msgService.findById(2L).getApiKey();
		String jgMasterSecret = msgService.findById(2L).getSecret();
		String conten = jgApiKey + ":" + jgMasterSecret;// "09c372b1920122d55f7127cc:38d6686004d7921aac4309d1"
		String base64_auth_string = Base64.getEncoder().encodeToString(
				conten.getBytes());
		try {
			String msg_Id = RedisCilent
					.getString(CacheConstants.SEND_MSGBYJG_MSGID + mobile);
			if (StringHelper.isNotEmpty(msg_Id)) {
				String url = "https://api.sms.jpush.cn/v1/codes/" + msg_Id
						+ "/valid";
				resultMap = HttpUtils.invokePostaddH(url, params, 5000,
						base64_auth_string, 1);
				RedisCilent.delKey(CacheConstants.SEND_MSGBYJG_MSGID + mobile);
			} else {
				logger.info("该手机号msgId为空，手机号为：{}", mobile);
				// {"code":"-1111","message":"invalid code"}
				resultMap.put("code", "-1111");
				resultMap.put("message", "缓存中不存在该手机号对应的msg_id");
			}

			// System.out.println(result);
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return resultMap;
	}

	/**
	 * 极光短信发送，
	 * 
	 * @param mobile
	 *            接收短信为英文,（英文逗号）间隔开
	 * @param content
	 * @param status
	 *            0 验证码
	 * @return
	 */
	public Boolean sendMsgByJG(String mobile, String content) {
		// 发送验证码
		boolean t = false;
		Map<String, String> params = new HashMap<>();
		params.put("temp_id", "5");
		params.put("mobile", mobile);
		String conten = "09c372b1920122d55f7127cc:38d6686004d7921aac4309d1";
		String base64_auth_string = Base64.getEncoder().encodeToString(
				conten.getBytes());
		try {
			String result = HttpUtils.invokePostAddAuth(
					"https://api.sms.jpush.cn/v1/codes", params, 5000,
					base64_auth_string);
			t = true;
			logger.info("极光发送验证码返回的msgId={},mobile={}", result, mobile);// {"msg_id":"4c40ec52-56e3-4868-be80-95d4eb5a4c48"}
			JSONObject resultObject = new JSONObject(result);
			RedisCilent.setString(CacheConstants.SEND_MSGBYJG_MSGID + mobile,
					resultObject.getString("msg_id"), 300);

		} catch (ClientProtocolException e) {
			logger.info("极光发送验证码短信异常！mobile={}", mobile);
			logger.error("极光发送验证码短信异常", e);
		} catch (IOException e) {
			logger.info("极光发送验证码短信异常！mobile={}", mobile);
			logger.error("极光发送验证码短信异常", e);
		}
		return t;
	}

	public Returnsms XMLStringToBean(String xmlStr) {
		Returnsms ben = new Returnsms();
		try {
			JAXBContext context = JAXBContext.newInstance(Returnsms.class);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			ben = (Returnsms) unmarshaller.unmarshal(new StringReader(xmlStr));
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return ben;
	}

	/**
	 * 短信发送，内容自定义接口
	 * 
	 * @param mobile
	 *            接收短信为英文,（英文逗号）间隔开
	 * @param content
	 * @param status
	 *            0 验证码
	 * @return
	 */
	public boolean sendMsgContentCustom(String mobile, String content) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(content);

		try {
			params.put("content", new String(buffer.toString()
					.getBytes("UTF-8")));
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		params.put("mobile", mobile);
		String result = "";
		boolean t = false;
		try {
			result = HttpUtils.invokePostForm(this.host, params, 5000);
			Returnsms sb = new Returnsms();
			sb = this.XMLStringToBean(result);
			logger.info("params:{}", params);
			logger.info("Send msg Result:{}", result);
			if (sb.getMessage().equals("ok")) {
				t = true;
			} else {
				logger.info("Send msg fail mobile:{} , Result:{}", mobile,
						result);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return t;
	}
}
